package com.polaris.live.ui.honor

import android.os.Bundle
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.StringUtils
import com.lxj.xpopup.XPopup
import com.polaris.live.R.color
import com.polaris.live.R.drawable
import com.polaris.live.adapter.HonorWallAdapter
import com.polaris.live.adapter.HonorWallGameAdapter
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.databinding.FragmentRichCharmHonorBinding
import com.polaris.live.dialog.HonorBannerDialog
import com.polaris.live.manager.DownFileManager
import com.polaris.live.resp.back_resp.UserMedalGame
import com.polaris.live.resp.back_resp.UserMedalVo
import com.polaris.live.resp.bean.GameHonorNumBean
import com.polaris.live.translation.R
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.viewmodel.HonorViewModel
import com.polaris.live.widget.refresh.EmptyView
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.math.min

/**
 * RichCharmHonorFragment
 *
 * @author Created by 半仙 on 2024/4/20/020 14:16
 */
class RichCharmHonorFragment : BaseVbFragment<HonorViewModel, FragmentRichCharmHonorBinding>() {

    private val mAdapter by lazy { HonorWallAdapter(lifecycleScope) }

    private val mGameAdapter by lazy { HonorWallGameAdapter() }

    private val mEmptyView by lazy { EmptyView(requireContext()) }

    private val mUserMedalVo: String? by lazy {
        arguments?.getString("honor")
    }

    private val mUserMedalGame: String? by lazy {
        arguments?.getString("honor_game")
    }

    private val mUserId: Long? by lazy {
        arguments?.getLong("userId")
    }

    private val mLoadList = ConcurrentLinkedQueue<UserMedalVo>()

    override fun initView(savedInstanceState: Bundle?) {
        mGameAdapter.setGridSpanSizeLookup { gridLayoutManager, viewType, _ ->
            if (viewType == HonorWallGameAdapter.TYPE_NUM) {
                gridLayoutManager.spanCount
            } else {
                1
            }
        }
        mBinding.itemRecycler.apply {
            itemAnimator = null
            layoutManager = GridLayoutManager(context, 3, GridLayoutManager.VERTICAL, false)
        }
        val userMedalVo = mUserMedalVo
        val userMedalGame = mUserMedalGame
        if (userMedalVo != null) {
            mBinding.itemRecycler.adapter = mAdapter
            mAdapter.setList(JsonUtils.fromJson<List<UserMedalVo>>(userMedalVo))
        } else {
            if (userMedalGame != null) {
                initGameRecycler(JsonUtils.fromJson<List<UserMedalGame>>(userMedalGame))
            }
        }

        val notHavaString = if (mUserId != null && mUserId != UserManager.getUserId()) {
            StringUtils.getString(R.string.other_not_hava_honor)
        } else {
            StringUtils.getString(R.string.you_dont_hava_honor)
        }

        mEmptyView.setEmptyTip(
            drawable.honor_wall_not_have,
            notHavaString
        )
        mAdapter.setEmptyView(mEmptyView)
        initListener()

        if (mUserMedalVo != null) {
            mAdapter.data.forEach {
                isNeedAdd(it)
            }
        } else if (mUserMedalGame != null) {
            mGameAdapter.data.forEach {
                if (it is UserMedalVo) {
                    isNeedAdd(it)
                }
            }
        }

        loadPag()
    }

    private fun initListener() {
        mAdapter.setOnItemClickListener { _, _, position ->
            XPopup.Builder(context)
                .shadowBgColor(ColorUtils.getColor(color.color_000_85))
                .isDestroyOnDismiss(true)
                .asCustom(HonorBannerDialog(requireContext(), mAdapter.data, position))
                .show()
        }

        mGameAdapter.setOnItemClickListener { _, _, position ->
            val honorList = mGameAdapter.data
            //区间查找
            val start = (position downTo 0).firstOrNull { honorList[it] is GameHonorNumBean }
                ?: return@setOnItemClickListener
            val end = (position until honorList.size).firstOrNull { honorList[it] is GameHonorNumBean }
                ?: honorList.size
            val showList = if (end == 0) {
                emptyList()
            } else {
                honorList.subList(min(start + 1, end), end)
                    .mapNotNull { it as? UserMedalVo }
            }

            if (showList.isNotEmpty()) {
                val item = honorList[position] as? UserMedalVo
                val indexOf = showList.indexOfFirst { it.medalId == item?.medalId }

                XPopup.Builder(context)
                    .shadowBgColor(ColorUtils.getColor(color.color_000_85))
                    .isDestroyOnDismiss(true)
                    .asCustom(HonorBannerDialog(requireContext(), showList, indexOf))
                    .show()
            }
        }
    }

    private fun isNeedAdd(userMedalVo: UserMedalVo) {
        val path = userMedalVo.pagUrl?.let { FileUtils.getFilePath(FileUtils.getPagFile(), it) }
        path?.let {
            if (!File(it).exists()) {
                mLoadList.add(userMedalVo)
            }
        }
    }

    private fun loadPag() {
        if (mLoadList.isEmpty()) return
        val poll = mLoadList.poll()
        if (poll == null) {
            loadPag()
            return
        }
        lifecycleScope.launch(CoroutineScopeManager.ioDispatcher) {
            val loadFileCallback =
                poll.pagUrl?.let { DownFileManager.loadFileCallback(FileUtils.getPagFile(), it) }
            withContext(CoroutineScopeManager.mainDispatcher) {
                loadFileCallback?.let {
                    if (mUserMedalVo?.isNotEmpty() == true) {
                        val indexOf = mAdapter.data.indexOfFirst { it.medalId == poll.medalId }
                        mAdapter.notifyItemChanged(indexOf)
                    } else {
                        mGameAdapter.notifyDataSetChanged()
                    }
                    loadPag()
                }
            }
        }
    }

    private fun initGameRecycler(userMedalGame: List<UserMedalGame>?) {
        val list = mutableListOf<Any>()
        userMedalGame?.forEach {
            list.add(GameHonorNumBean(it.count, it.hasCount, it.name))
            list.addAll(it.medals)
        }
        mBinding.itemRecycler.adapter = mGameAdapter
        mGameAdapter.setList(list)
    }

}